{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "# os.environ[\"CUDA_VISIBLE_DEVICES\"] = \"1\"\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# load dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_train = np.load('E:/IDS/alldata/12/RUS+SMOTE/data2.npy')\n",
    "y_train = np.load('E:/IDS/alldata/12/RUS+SMOTE/label2_10.npy')\n",
    "\n",
    "x_test = np.load('E:/IDS/alldata/12/test/data.npy')\n",
    "y_test = np.load('E:/IDS/alldata/12/test/label_10.npy')\n",
    "\n",
    "x_val = np.load('E:/IDS/alldata/12/val/data.npy')\n",
    "y_val = np.load('E:/IDS/alldata/12/val/label_10.npy')\n",
    "\n",
    "\n",
    "print(x_train.shape,y_train.shape,x_test.shape,y_test.shape,x_val.shape,y_val.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_train = np.expand_dims(x_train,2)\n",
    "x_test = np.expand_dims(x_test,2)\n",
    "x_val = np.expand_dims(x_val,2)\n",
    "# label one-hot\n",
    "from keras.utils import to_categorical\n",
    "y_train = to_categorical(y_train)\n",
    "y_test = to_categorical(y_test)\n",
    "y_val = to_categorical(y_val)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_train.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# train model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from keras.layers import Conv1D,MaxPooling1D,Dense,Dropout,Input,Flatten,GlobalAveragePooling1D\n",
    "from keras.layers.normalization import BatchNormalization\n",
    "from keras.models import Model\n",
    "from keras.optimizers import Nadam\n",
    "from keras import initializers\n",
    "from keras import regularizers\n",
    "np.random.seed(4)\n",
    "import pickle\n",
    "import math\n",
    "from keras.callbacks import LearningRateScheduler, ModelCheckpoint\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "n_obs,feature, depth = x_train.shape\n",
    "batch_size = 256\n",
    "def build_model():\n",
    "    input_singal = Input(shape=(feature,depth))\n",
    "    x = Conv1D(32,3,activation='relu',padding='same',kernel_initializer='he_uniform')(input_singal)\n",
    "    x = Conv1D(32,3,activation='relu',padding='same',kernel_initializer='he_uniform')(x)\n",
    "    x = MaxPooling1D(pool_size=2,strides=2)(x)\n",
    "    x = Dropout(0.2)(x)\n",
    "    x = BatchNormalization()(x)\n",
    "    \n",
    "    x = Conv1D(64,3,activation='relu',padding='same',kernel_initializer='he_uniform')(x)\n",
    "    x = Conv1D(64,3,activation='relu',padding='same',kernel_initializer='he_uniform')(x) \n",
    "    x = MaxPooling1D(pool_size=2,strides=2)(x)\n",
    "    x = Dropout(0.2)(x)\n",
    "    x = BatchNormalization()(x)    \n",
    "    \n",
    "    x = Flatten()(x)\n",
    "    x = Dense(32,activation='relu')(x)\n",
    "    x = Dense(10,activation='softmax')(x)   #UNSW-NB15 is 2 and 10,CICIDS2017 is 15\n",
    "    model = Model(inputs=input_singal,outputs=x)\n",
    "    \n",
    "    return model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model =  build_model()\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import keras\n",
    "import time\n",
    "time_start = time.time()\n",
    "\n",
    "reduce_lr = keras.callbacks.ReduceLROnPlateau(moniter='val_loss',\n",
    "                                              factor=0.1,\n",
    "                                              patience=10)\n",
    "nadam = Nadam(lr=0.008, beta_1=0.9, beta_2=0.999, epsilon=1e-08, schedule_decay=0.004)\n",
    "model.compile(loss = \"categorical_crossentropy\",optimizer = \"nadam\", metrics = [\"accuracy\"])\n",
    "\n",
    "history = model.fit(x_train, y_train, \n",
    "                    epochs=100, \n",
    "                    batch_size=batch_size, \n",
    "                    verbose=2,\n",
    "                    validation_data=(x_val, y_val),\n",
    "                    callbacks=[reduce_lr])\n",
    "time_end = time.time()\n",
    "train_time = time_end - time_start\n",
    "print(\"train_time:\",train_time)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "scores = model.evaluate(x_test, y_test)\n",
    "print(\"test_loss = \", scores[0],\"test_accuracy = \", scores[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.save('E:/IDS/alldata/12/RUS+SMOTE/CNN_RUS_10(2ci).h5')#save model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# test model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import time\n",
    "time_start = time.time()\n",
    "\n",
    "y_pred_onehot  = model.predict(x_test)  #返回的是在类别上的概率分布.It returns the probability distribution on the category\n",
    "y_pred_label=np.argmax(y_pred_onehot,axis=1)#概率最大的类别就是预测类别.The category with the highest probability is the prediction category\n",
    "\n",
    "time_end = time.time()\n",
    "test_time = time_end - time_start\n",
    "print(\"test_time:\",test_time)\n",
    "\n",
    "# np.savetxt(\"E:/IDS/cicdata/GMM+SMOTE_77/2ci/CNN_pred_15.txt\",y_pred_label)  \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_true_onehot=y_test\n",
    "y_true_label=np.argmax(y_true_onehot,axis=1)\n",
    "# np.savetxt(\"E:/IDS/cicdata/GMM+SMOTE_77/2ci/CNN_true_15.txt\",y_true_label)  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# -*-coding:utf-8-*-\n",
    "from sklearn.metrics import confusion_matrix\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "labels = ['Normal','Analysis','Backdoor','DoS','Exploits','Fuzzers','Generic','Reconnaissance','Shellcode','Worms']  #class name\n",
    "\n",
    "y_true = y_true_label\n",
    "y_pred  = y_pred_label\n",
    "\n",
    "tick_marks = np.array(range(len(labels))) + 0.5\n",
    "\n",
    "def plot_confusion_matrix(cm, title='Confusion Matrix', cmap=plt.cm.binary):\n",
    "    plt.imshow(cm, interpolation='nearest', cmap=plt.cm.Blues) \n",
    "    plt.title(title)\n",
    "    plt.colorbar()\n",
    "    xlocations = np.array(range(len(labels)))\n",
    "    plt.xticks(xlocations, labels, rotation=90)\n",
    "    plt.yticks(xlocations, labels)\n",
    "    plt.ylabel('True label')\n",
    "    plt.xlabel('Predicted label')\n",
    "\n",
    "\n",
    "cm = confusion_matrix(y_true, y_pred) \n",
    "np.set_printoptions(precision=2)  \n",
    "cm_normalized = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]  \n",
    "\n",
    "plt.figure(figsize=(15, 13), dpi=120)\n",
    "\n",
    "ind_array = np.arange(len(labels))\n",
    "x, y = np.meshgrid(ind_array, ind_array)\n",
    "\n",
    "for x_val, y_val in zip(x.flatten(), y.flatten()):\n",
    "    c = cm_normalized[y_val][x_val]\n",
    "    if c > 0.001:\n",
    "        plt.text(x_val, y_val, \"%0.2f\" % (c,), color='red', fontsize=13, va='center', ha='center')\n",
    "# offset the tick\n",
    "plt.gca().set_xticks(tick_marks, minor=True)\n",
    "plt.gca().set_yticks(tick_marks, minor=True)\n",
    "plt.gca().xaxis.set_ticks_position('none')\n",
    "plt.gca().yaxis.set_ticks_position('none')\n",
    "plt.grid(True, which='minor', linestyle='-')\n",
    "plt.gcf().subplots_adjust(bottom=0.15)\n",
    "\n",
    "plot_confusion_matrix(cm_normalized, title='MLP_12_10_ROS Normalized confusion matrix')  \n",
    "#plt.savefig('/home/hll/IDS/alldata/cm/confusion_matrix.png', format='png') \n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(cm)  #Confusion matrix"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# multi-class evaluation indicators"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn import metrics\n",
    "from sklearn.metrics import classification_report\n",
    "\n",
    "target_names = ['Normal','Analysis','Backdoor','DoS','Exploits','Fuzzers','Generic','Reconnaissance','Shellcode','Worms']\n",
    "print(classification_report(y_true,y_pred,target_names=target_names))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "acc = metrics.accuracy_score(y_true,y_pred) \n",
    "f1 = metrics.f1_score(y_true, y_pred,average='weighted')\n",
    "pre = metrics.precision_score(y_true, y_pred, labels=None, pos_label=1, average='weighted')  #DR\n",
    "recall = metrics.recall_score(y_true, y_pred, labels=None, pos_label=1, average='weighted', sample_weight=None)\n",
    "\n",
    "print(\"acc:\",acc)\n",
    "print(\"pre:\",pre)\n",
    "print(\"DR=recall:\",recall)\n",
    "print(\"f1:\",f1)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# # binary-class evaluation indicators"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "TP=cm[1,1]\n",
    "FP=cm[0,1]\n",
    "FN=cm[1,0]\n",
    "TN=cm[0,0]\n",
    "\n",
    "acc = (TP+TN)/(TP+TN+FP+FN)\n",
    "print(\"acc:\",acc)\n",
    "\n",
    "DR = TP/(TP+FN)  \n",
    "print(\"DR:\",DR)\n",
    "\n",
    "FPR = FP/(FP+TN)  #FAR\n",
    "print(\"FPR:\",FPR)\n",
    "\n",
    "recall =TP/(TP+FN)\n",
    "print(\"recall：\",recall)  \n",
    "\n",
    "precision = TP/(TP+FP)\n",
    "print(\"precision:\",precision)\n",
    "\n",
    "f1 = (2*precision*recall)/(precision+recall)\n",
    "print(\"f1:\",f1)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
